package com.coderman.modelfly.utils;

import com.coderman.modelfly.config.AnnotationConfig;
import com.coderman.modelfly.config.BeanConfig;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by ${fanchunshuai} on 2017-6-7.
 *
 * @author 58
 * @version: V1.0
 * @Desc:
 * @Copyright (c) 2017 58到家-版权所有
 */
public class GenerateTools {

    /**
     * 生成类头部
     * 1.包名
     * 2.引用列表
     * 3.类注释
     * @param clazzBean
     * @param desc
     * @return
     */
    public static String generateClassHead(BeanConfig clazzBean,String desc){
        StringBuffer buffer = new StringBuffer();

        if(!clazzBean.getPackageName().startsWith("package")){
            buffer.append("package "+clazzBean.getPackageName());
        }else{
            buffer.append(clazzBean.getPackageName());
        }

        if(!buffer.toString().endsWith(";")){
            buffer.append(";");
        }

        buffer.append("\n\n");

        if(clazzBean.getImportClazz() != null && !clazzBean.getImportClazz().isEmpty()){
            for (String str:clazzBean.getImportClazz()){
                if(!str.startsWith("import ")){
                    buffer.append("import "+str);
                }
                if(!str.endsWith(";")){
                    buffer.append(";");
                }
                buffer.append("\n");
            }
        }

        buffer.append("\n\n");

        //生成类注释

        buffer.append("/**\n");


        if(StringUtils.isNotBlank(clazzBean.getAuthor())){
            buffer.append( " * Created by ");
            buffer.append(clazzBean.getAuthor());
            buffer.append(" on "+ DateBuilder.convertDateToString(new Date(),"yyyy-MM-dd")+"\n");
            buffer.append(" * @author: "+clazzBean.getAuthor()+"\n");
        }



        buffer.append(" * @version: "+"V1.0"+"\n");


        if(StringUtils.isNotBlank(desc)){
            buffer.append(" * @desc: "+desc+"\n");
        }
        if (StringUtils.isNotBlank(clazzBean.getCopyright())){
            buffer.append(" * @copyright: "+clazzBean.getCopyright()+"\n");
        }
        buffer.append(" */\n");

        return buffer.toString();
    }


    /**
     * 生成类上的注解
     * @param classAnnotation
     * @param tableName
     * @return
     */
    public static String generateClassAnnotation(AnnotationConfig classAnnotation,String tableName){
        StringBuffer buffer = new StringBuffer();

        //生成类注解
        if(classAnnotation !=null){
            if(StringUtils.isNotBlank(classAnnotation.getValueModel())){
                switch (classAnnotation.getValueModel()){
                    case "1":
                        buffer.append("@");
                        buffer.append(classAnnotation.getAnnotionName());
                        buffer.append("(");

                        buffer.append(classAnnotation.getAttributeName());
                        buffer.append("=\"");
                        //插入自定义类型值
                        buffer.append(classAnnotation.getAttributeValue());
                        buffer.append("\")\n");
                        break;
                    case "2":
                        break;
                    case "3":
                        buffer.append("@");
                        buffer.append(classAnnotation.getAnnotionName());
                        buffer.append("(");
                        buffer.append(classAnnotation.getAttributeName());
                        buffer.append("=\"");
                        //插入数据库名
                        buffer.append(tableName);
                        buffer.append("\")\n");
                        break;
                    case "5":
                        buffer.append("@");
                        buffer.append(classAnnotation.getAnnotionName());
                        buffer.append("(");
                        buffer.append(classAnnotation.getAttributeName());
                        buffer.append("=\"");
                        //插入bean全限定名
                        //String fullClassPath = clazzBean.getPackageName().replace("package","").trim()+"."+clazzName;
                        //buffer.append(fullClassPath);
                        buffer.append("\")\n");
                        break;
                    default:
                        System.out.println("error");
                }
            }else{
                buffer.append("@");
                buffer.append(classAnnotation.getAnnotionName()+"\n");
            }

        }
        return buffer.toString();
    }


    /**
     * 生成类描述  public class .... extends ....  implements ....
     * @param clazzBean
     * @param clazzName
     * @return
     */
    public static String generateClassDesc(BeanConfig clazzBean,String clazzName){
        StringBuffer buffer = new StringBuffer();
        //生成类描述
        buffer.append("public class ");
        buffer.append(clazzName);
        if(StringUtils.isNotBlank(clazzBean.getImplementsClazz())){
            buffer.append(" implements ").append(clazzBean.getImplementsClazz());
        }
        if(StringUtils.isNotBlank(clazzBean.getExtendsClazz())){
            buffer.append(" extends ").append(clazzBean.getExtendsClazz());
        }
        buffer.append(" {\n");
        return buffer.toString();
    }

    /**
     * 根据类和字段变量列表生成 变量列表，get/set方法， toString方法
     * @param className
     * @param variableList
     * @return
     */
    public static Map<String,String> generateVariableList(AnnotationConfig idAnnotation,AnnotationConfig fieldAnnotation,String className, List<String> variableList){
        //bean 变量列表
        StringBuffer variable = new StringBuffer();
        StringBuffer getSet = new StringBuffer();
        StringBuffer toString = new StringBuffer("    @Override\n" +
                "    public String toString() { \n        return \""+className+"{\" + ");
        Map<String,String> varMap = new HashMap<String,String>();

        for (int i = 0;i < variableList.size();i ++ ){
            String [] varArray = variableList.get(i).split("-");
            Map<String,String> map = generateOneField(idAnnotation,fieldAnnotation,varArray,(i+1));
            variable.append(map.get("varObj"));
            String getSetStr = GenerateTools.generateGetSetMethod(map.get("varType"),map.get("varName"));
            getSet.append(getSetStr);
            if(i == 0){
                toString.append("\""+map.get("varName")+"=\" + "+map.get("varName")+" + \n");
            }else{
                if("String".equals(map.get("varType"))){
                    toString.append("            \", "+map.get("varName")+"='\" + "+ map.get("varName") + " + '\\'' +\n");
                }else{
                    toString.append("            \", "+map.get("varName")+"=\" + "+map.get("varName")+" +\n");
                }
            }
        }

        toString.append("        '}';\n" +
                "    }");

        //变量列表
        varMap.put("varList",variable.toString());
        //getset列表
        varMap.put("getSetList",getSet.toString());
        //tostring方法
        varMap.put("toString",toString.toString());
        return varMap;



    }


    public static Map<String,String> generateOneField(AnnotationConfig idAnnotation,AnnotationConfig fieldAnnotation,String [] varArray,int index){
        System.out.println(fieldAnnotation.toString()+"----------------------------------");
        Map<String,String> map = new HashMap<>();

        StringBuffer  varBuffer = new StringBuffer();
        if(varArray.length == 4){
            varBuffer.append("    /** ");
            varBuffer.append(varArray[3]);
            varBuffer.append(" **/ \n");
        }

        StringBuffer annotation = new StringBuffer();

        //对id注解进行处理
        if(idAnnotation !=null ){
            if("id".equals(varArray[1])) {
                if(StringUtils.isNotBlank(idAnnotation.getValueModel())){
                    annotation.append(generateFieldAnnotation(idAnnotation,index,varArray[1]));
                }else{
                    annotation.append("    @");
                    annotation.append(idAnnotation.getAnnotionName()+"\n");
                }
            }
        }


        //对普通注解进行处理
        if(fieldAnnotation != null && StringUtils.isNotBlank(fieldAnnotation.getValueModel())){
            annotation.append(generateFieldAnnotation(fieldAnnotation,index,varArray[1]));
        }else{
            if (fieldAnnotation != null){
                annotation.append("    @");
                annotation.append(fieldAnnotation.getAnnotionName()+"\n");
            }
        }

        varBuffer.append(annotation.toString());
        varBuffer.append("    private  ");


        String varType = GenerateTools.getVarType(varArray[2]);
        varBuffer.append(varType + " ");

        String varName = "";

        if(varArray[1].contains("_")){
            String [] varArr = varArray[1].split("_");
            varName += varArr[0];
            varBuffer.append(varArr[0]);

            for (int i = 1 ;i < varArr.length; i++){
                char[] cs= varArr[i].toCharArray();
                cs[0]-=32;
                String v = String.valueOf(cs);
                varBuffer.append(v);
                varName+=v;
            }
        }else{
            varBuffer.append(varArray[1]);
            varName = varArray[1];
        }

        varBuffer.append(";\n\n");

        map.put("varObj",varBuffer.toString());
        map.put("varName",varName);
        map.put("varType",varType);

        return map;
    }

    private static String generateFieldAnnotation(AnnotationConfig fieldAnnotation,int index,String dbColumnValue){
        StringBuffer annotation = new StringBuffer("");
            switch (fieldAnnotation.getValueModel()) {
                case "1":
                    annotation.append("    @");
                    annotation.append(fieldAnnotation.getAnnotionName());
                    annotation.append("(");
                    annotation.append(fieldAnnotation.getAttributeName());
                    annotation.append("=\"");
                    //插入自定义类型值
                    annotation.append(fieldAnnotation.getAttributeValue());
                    annotation.append("\")\n");
                    break;
                case "2":
                    annotation.append("    @");
                    annotation.append(fieldAnnotation.getAnnotionName());
                    annotation.append("(");
                    annotation.append(fieldAnnotation.getAttributeName());
                    annotation.append("=");
                    //插入自增值
                    annotation.append(index);
                    annotation.append(")\n");
                    break;
                case "4":
                    annotation.append("    @");
                    annotation.append(fieldAnnotation.getAnnotionName());
                    annotation.append("(");
                    annotation.append(fieldAnnotation.getAttributeName());
                    annotation.append("=\"");
                    //插入数据库字段
                    annotation.append(dbColumnValue);
                    annotation.append("\")\n");
                    break;
                case "5":

                    default:
                        System.out.println("error......");
            }
            return annotation.toString();
        }

    /**
     * 生成 get / set方法
     * @param varType
     * @param varName
     * @return
     */
    public static String generateGetSetMethod(String varType,String varName){
        StringBuffer buffer = new StringBuffer();
        buffer.append("    public ");
        buffer.append(varType);
        char[] cs = varName.toCharArray();
        cs[0]-=32;
        String upName = String.valueOf(cs);
        buffer.append(" get" + upName +" (){ return "+varName+"; }\n");
        buffer.append("    public void  set");
        buffer.append(upName+"(");
        buffer.append(varType+" "+varName+") { this.");
        buffer.append(varName+" = "+varName+";}\n\n");
        return buffer.toString();
    }

    /**
     * 获取字段类型对应的 封装类型
     * @param varType
     * @return
     */
    public static String getVarType(String varType){
        if(varType.contains("(")){
            varType = varType.substring(0,varType.indexOf("("));
        }

        switch (varType){
            case "int":
                return "Integer";
            case "varchar":
                return "String";
            case "bigint":
                return "Long";
            case "datetime":
                return "Date";
            case "decimal":
                return "Double";
            case "text":
                return "String";
            case "tinyint":
                return "Short";
            case "timestamp":
                return "Date";
            default:
                return "null type";
        }
    }


    /**
     * 将生成的类写入文件，生成.java文件
     * @param className
     * @param head
     * @param varList
     * @param getSetList
     * @param toString
     * @return
     * @throws IOException
     */
    public static boolean writeFile(String classPath,String className,String head,String varList,String getSetList,String toString) throws IOException {
        File fileDir = new File(classPath);
        if(!fileDir .exists()  && !fileDir .isDirectory()){
            fileDir.mkdir();
        }

        String fileName = classPath+"\\"+className+".java";
        File file = new File(fileName);
        String classInfo = head + varList + getSetList + toString+"\n}";
        FileUtils.writeStringToFile(file,classInfo,"UTF-8");
        return false;
    }



    /**
     * 根据表名生成类名
     * @param tableName
     * @return
     */
    public static String genearateBeanName(String tableName,String prefix,String suffix){
        String s = "";
        if(tableName.contains("_")){
            for (String var : tableName.split("_")){
                char[] cs = var.toCharArray();
                cs[0]-=32;
                String upName = String.valueOf(cs);
                s+=upName;
            }

        }else{
            char[] cs = tableName.toCharArray();
            cs[0] -= 32;
            s = String.valueOf(cs);
        }

        if(StringUtils.isNotBlank(prefix)){
            s = prefix+s;
        }
        if(StringUtils.isNotBlank(suffix)){
            s = s+suffix;
        }
        return s;
    }
}
